/*
 * @Author: yuelei 
 * @Date: 2018-03-27 13:23:19 
 * @Last Modified by: Yuelei
 * @Last Modified time: 2018-05-17 00:01:41
 */
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router, Route, Link, Switch ,Redirect} from 'react-router-dom';
import { Layout } from "antd";
import { withRouter } from "react-router";
import PropTypes from "prop-types";

import StatusBar from "./component/StatusBar/index.jsx";

import ClassService from "./service/class";
import BrandService from "./service/brand";
import ProductService from "./service/product";
import OrderService from "./service/order";

import ClassPage from "./page/Class/index.jsx";
import ShoppingCart from './page/ShoppingCart/index.jsx'
import Welcome from 'page/welcome/index.jsx';
import Finish from 'page/finish/index.jsx';
import Product_details from 'page/product_details/index.jsx'
import "./app.scss";

// Temp Com
class StatusBarLayout extends React.Component {
  render() {
    const { history, names } = this.props;
    const hide_status_bar = history.location.pathname === "/welcome";

    return !hide_status_bar ?
      <Layout.Header className="app_status_bar">
        <StatusBar names={names} />
      </Layout.Header> :
      <div></div>
  }
}


StatusBarLayout.propTypes = {
  names: PropTypes.objectOf(PropTypes.string),  // {"url1":"name1", "url2":"name2"}
}

StatusBarLayout = withRouter(StatusBarLayout);

class App extends React.Component {
  constructor(props) {
    super(props)
    this.state = {

      // User Info
      user: "",               // str
      tel: "",                // str
      sex: "",          // str, "male" or "female"

      current_cls_id: undefined,      // int, default undefined
      current_brand_id: undefined,    // int, default undefined
      classes: [],                    // class[ brand[ productions ]]

      shopping_cart: {
        productions: {
     
         
        },
        notes: ""
      },

      is_uploading: false // is order uploading
    }
  }

  /**
   * App Component 加载完成后立即获取 classes 列表
   */
  componentDidMount() {
    ClassService.getClassList().then(classes => {

      console.log(`Got classes list.`, classes);

      // 未考虑 classes 长度为0的情况。
      const default_cls_idx = 0;
      const cls_id = classes[default_cls_idx].id;

      BrandService.getBrands(cls_id).then(brands => {

        console.log("Got brands list.", brands);
        classes[default_cls_idx].brands = brands;
        const default_brand_idx = 0;
        this.setState({
          classes,
          current_cls_id: classes[default_cls_idx].id,
        })

      }, err => {
        console.warn(`Error in getting brands list of class[${cls_id}]. ${err}`)
      });

    }, err => {
      console.warn(`Error in getting classes list. ${err}`);
    })
  }

  // /**
  //  * setState wrapper, for data tracing.
  //  */
  // new_state_value = (attrib, new_value) => {
  //     this.setState({attrib: new_value});
  // }

  handle_name_change(new_name) {
    this.setState({ user: new_name });
  }

  handle_tel_change(new_tel) {
    this.setState({ tel: new_tel })
  }

  handle_sex_change(new_sex) {
    const enums = ["male", "female"];
    if (enums.includes(new_sex)) {
      this.setState({ sex: new_sex });
    } else {
      console.error(`Invalid Sex string[${new_sex}]`);
    }
  }

  /**
   * 通过返回的 promise 及 try...catch 来获取异步状态。
   * @param {int} cls_id 
   * @returns Promise or undefined
   */
  handle_class_change(cls_id) {
    const { classes } = this.state;
    const idx = classes.findIndex((val, idx, err) => val.id === cls_id); // the index of class in classes.
    if (classes[idx].brands !== undefined) {
      this.setState({ current_cls_id: cls_id, current_brand_id: undefined });
    } else {
      return BrandService.getBrands(cls_id).then(brands => {

        console.log(`Got brands list. `, brands);
        classes[idx].brands = brands;
        this.setState({ classes: [...classes], current_cls_id: cls_id, current_brand_id: undefined }); // 性能靶点

      }, err => {
        console.warn(`Error in getting brands list of class[${cls_id}]. ${err}`)
      });
    }
  }

  /**
   * 通过返回的 promise 及 try...catch 来获取异步状态。
   * @param {int} brand_id 
   * @returns Promise or undefined
   */
  handle_brand_change(brand_id) {
    const { classes, current_cls_id } = this.state;
    const { brands } = classes.find((val, idx, err) => val.id === current_cls_id);
    const brand_idx = brands.findIndex((val, idx, err) => val.id === brand_id); // the index of class in classes.

    if (brands[brand_idx].productions === undefined) {

      return ProductService.getProductions({ cls_id: current_cls_id, brand_id: brand_id }).then(productions => {

        console.log("Get Productions. ", productions);
        brands[brand_idx].productions = productions;
        this.setState({ current_brand_id: brand_id, classes: [...classes] });

      }, res => {

        console.warn("Get Productions Failed. ", err);

      })

    } else {
      // Use Cached data.
      this.setState({ current_brand_id: brand_id });

    }
    // this.setState({current_brand_id: brand_id});
  }

  handle_item_count_change({ prodId, new_count }) {
    const { shopping_cart } = this.state;
    const { productions } = shopping_cart;

    if (new_count === 0 && productions[prodId] === 1) {
      // minus item
      delete productions[prodId];
    } else {
      // add item
      productions[prodId] = {
        count: new_count,
        note: productions[prodId] !== undefined ? productions[prodId].note : ""
      };
    }

    this.setState({ shopping_cart: Object.assign({}, shopping_cart) });
  }
  handle_item_note_change({ prodId, new_notes}) {
    const { shopping_cart } = this.state;
    const { productions } = shopping_cart;

    productions[prodId].note = new_notes;

    console.log(`${prodId}${new_notes}`),


    
    this.setState({ shopping_cart: Object.assign({}, shopping_cart) });
  }
  handle_note_change(new_note) {
    const { shopping_cart } = this.state;
    shopping_cart.notes = new_note;
    this.setState({ shopping_cart: Object.assign({}, shopping_cart) });
  }

  /**
   * 通过返回的 promise 来获取异步状态。
   * post失败通过promise.catch捕获
   * @returns Promise
   */
  handle_order_submit() {
    const { user, tel, sex, shopping_cart: { productions, notes } } = this.state;
    this.setState({ is_uploading: true })
    console.log(productions)
    return OrderService.postOrder(user, tel, sex, productions, notes).then(res => {
      console.log("Posted Order.", res);
      this.setState({ is_uploading: false });
      this.set_initial_user_state();
    }, err => {
      console.warn("Post Order Failed.", err);
      this.setState({ is_uploading: false });
      this.set_initial_user_state();
      throw "Post Failed";
    })
  }

  set_initial_user_state() {
    this.setState({ tel: "", user: "", sex: "female", shopping_cart: {productions: {}, notes:""} });
  }

  render() {
    const { current_brand_id, current_cls_id, classes, shopping_cart } = this.state;


    // 若不需要StatusBar显示页面名称，则不传该prop
    const status_bar_names = {
      "/classes/brands": "选择品牌",
      "/classes/productions_list": "选购产品",
      "/production_details": "产品详情",
      "/shopping_cart": "购物车",
    }

    const { user, tel, sex } = this.state;

    const welcome_page_props = {
      handle_name_change: this.handle_name_change.bind(this),
      handle_tel_change: this.handle_tel_change.bind(this),
      handle_sex_change: this.handle_sex_change.bind(this),
      user, tel, sex
    }
    const class_page_props = {
    handle_class_change: this.handle_class_change.bind(this),
      handle_brand_change: this.handle_brand_change.bind(this),
      current_brand_id, current_cls_id, classes
    }

    const product_page_props = {
      handle_item_count_change: this.handle_item_count_change.bind(this),
      current_brand_id, current_cls_id, classes, shopping_cart
    }

    const shopping_cart_page_props = {
      handle_item_count_change: this.handle_item_count_change.bind(this),
      handle_item_note_change: this.handle_item_note_change.bind(this),
      handle_note_change: this.handle_note_change.bind(this),
      handle_order_submit: this.handle_order_submit.bind(this),
      shopping_cart, classes,
      user, tel, sex
    }

    
    return (
      <Router>
        <Layout className="app_container">
          <StatusBarLayout names={status_bar_names} />
          <Layout style={{overflow:"scroll"}}>
            <Switch>
              <Route path='/welcome' render={() => <Welcome {...welcome_page_props} />} />
              <Route path='/classes' render={() => <ClassPage {...class_page_props} />} />
              <Route path="/shopping_cart" render={() => <ShoppingCart {...shopping_cart_page_props} />} />
              <Route path="/production_details" render={() => <Product_details {...product_page_props} />} />
              <Route path="/finish" render={() => <Finish is_uploading={this.state.is_uploading} />} />
              <Redirect from='/' to='/welcome' />
            </Switch>
          </Layout>
        </Layout>
      </Router>
    );
  }
}



ReactDOM.render(
  <App />,
  document.getElementById('app')
);